{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "d1f20875-c50d-46df-906b-49ec1d0c6002",
   "metadata": {},
   "source": [
    "## 10.10 VGGNet的实现\n"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "c90a18b9-d8e8-431c-856c-35f1e4ed05e1",
   "metadata": {},
   "source": [
    "### 1.任务描述\n",
    "\n",
    "使用TensorFlow实现VGGNet，对CIFAR-10数据集进行训练，实现多分类。"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "415ef9b0-5988-43c0-923c-d13d08bd02ca",
   "metadata": {},
   "source": [
    "### 2.知识准备\n",
    "\n",
    "见教程。\n"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "55043130-4496-43a3-803b-9bc1cea8b1b8",
   "metadata": {},
   "source": [
    "### 3.任务分析构\n",
    "\n",
    "定义一个VGGNet16的网络实现类，在该类中定义网络结构并定义表明参数传播方向的前向传播函数"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "435c6090-cfda-4f46-a550-22a368e41e4a",
   "metadata": {},
   "source": [
    "### 4.任务实施\n"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "ec75eb6c-5da3-467d-a471-ca3b47242dd6",
   "metadata": {},
   "source": [
    "执行代码"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "2ae9da58-e339-4d22-9f8d-ca255711d89e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 1/5\n",
      "1563/1563 [==============================] - 46s 27ms/step - loss: 1.9120 - sparse_categorical_accuracy: 0.2252 - val_loss: 1.8620 - val_sparse_categorical_accuracy: 0.2935\n",
      "Epoch 2/5\n",
      "1563/1563 [==============================] - 42s 27ms/step - loss: 1.5133 - sparse_categorical_accuracy: 0.4087 - val_loss: 1.6544 - val_sparse_categorical_accuracy: 0.4399\n",
      "Epoch 3/5\n",
      "1563/1563 [==============================] - 41s 26ms/step - loss: 1.1832 - sparse_categorical_accuracy: 0.5826 - val_loss: 1.1332 - val_sparse_categorical_accuracy: 0.5928\n",
      "Epoch 4/5\n",
      "1563/1563 [==============================] - 41s 26ms/step - loss: 0.9868 - sparse_categorical_accuracy: 0.6639 - val_loss: 0.9793 - val_sparse_categorical_accuracy: 0.6524\n",
      "Epoch 5/5\n",
      "1563/1563 [==============================] - 41s 26ms/step - loss: 0.8553 - sparse_categorical_accuracy: 0.7136 - val_loss: 0.9347 - val_sparse_categorical_accuracy: 0.6679\n",
      "Model: \"vgg16\"\n",
      "_________________________________________________________________\n",
      " Layer (type)                Output Shape              Param #   \n",
      "=================================================================\n",
      " conv2d (Conv2D)             multiple                  1792      \n",
      "                                                                 \n",
      " batch_normalization (BatchN  multiple                 256       \n",
      " ormalization)                                                   \n",
      "                                                                 \n",
      " activation (Activation)     multiple                  0         \n",
      "                                                                 \n",
      " conv2d_1 (Conv2D)           multiple                  36928     \n",
      "                                                                 \n",
      " batch_normalization_1 (Batc  multiple                 256       \n",
      " hNormalization)                                                 \n",
      "                                                                 \n",
      " activation_1 (Activation)   multiple                  0         \n",
      "                                                                 \n",
      " max_pooling2d (MaxPooling2D  multiple                 0         \n",
      " )                                                               \n",
      "                                                                 \n",
      " dropout (Dropout)           multiple                  0         \n",
      "                                                                 \n",
      " conv2d_2 (Conv2D)           multiple                  73856     \n",
      "                                                                 \n",
      " batch_normalization_2 (Batc  multiple                 512       \n",
      " hNormalization)                                                 \n",
      "                                                                 \n",
      " activation_2 (Activation)   multiple                  0         \n",
      "                                                                 \n",
      " conv2d_3 (Conv2D)           multiple                  147584    \n",
      "                                                                 \n",
      " batch_normalization_3 (Batc  multiple                 512       \n",
      " hNormalization)                                                 \n",
      "                                                                 \n",
      " activation_3 (Activation)   multiple                  0         \n",
      "                                                                 \n",
      " max_pooling2d_1 (MaxPooling  multiple                 0         \n",
      " 2D)                                                             \n",
      "                                                                 \n",
      " dropout_1 (Dropout)         multiple                  0         \n",
      "                                                                 \n",
      " conv2d_4 (Conv2D)           multiple                  295168    \n",
      "                                                                 \n",
      " batch_normalization_4 (Batc  multiple                 1024      \n",
      " hNormalization)                                                 \n",
      "                                                                 \n",
      " activation_4 (Activation)   multiple                  0         \n",
      "                                                                 \n",
      " conv2d_5 (Conv2D)           multiple                  590080    \n",
      "                                                                 \n",
      " batch_normalization_5 (Batc  multiple                 1024      \n",
      " hNormalization)                                                 \n",
      "                                                                 \n",
      " activation_5 (Activation)   multiple                  0         \n",
      "                                                                 \n",
      " conv2d_6 (Conv2D)           multiple                  590080    \n",
      "                                                                 \n",
      " batch_normalization_6 (Batc  multiple                 1024      \n",
      " hNormalization)                                                 \n",
      "                                                                 \n",
      " activation_6 (Activation)   multiple                  0         \n",
      "                                                                 \n",
      " max_pooling2d_2 (MaxPooling  multiple                 0         \n",
      " 2D)                                                             \n",
      "                                                                 \n",
      " dropout_2 (Dropout)         multiple                  0         \n",
      "                                                                 \n",
      " conv2d_7 (Conv2D)           multiple                  1180160   \n",
      "                                                                 \n",
      " batch_normalization_7 (Batc  multiple                 2048      \n",
      " hNormalization)                                                 \n",
      "                                                                 \n",
      " activation_7 (Activation)   multiple                  0         \n",
      "                                                                 \n",
      " conv2d_8 (Conv2D)           multiple                  2359808   \n",
      "                                                                 \n",
      " batch_normalization_8 (Batc  multiple                 2048      \n",
      " hNormalization)                                                 \n",
      "                                                                 \n",
      " activation_8 (Activation)   multiple                  0         \n",
      "                                                                 \n",
      " conv2d_9 (Conv2D)           multiple                  2359808   \n",
      "                                                                 \n",
      " batch_normalization_9 (Batc  multiple                 2048      \n",
      " hNormalization)                                                 \n",
      "                                                                 \n",
      " activation_9 (Activation)   multiple                  0         \n",
      "                                                                 \n",
      " max_pooling2d_3 (MaxPooling  multiple                 0         \n",
      " 2D)                                                             \n",
      "                                                                 \n",
      " dropout_3 (Dropout)         multiple                  0         \n",
      "                                                                 \n",
      " conv2d_10 (Conv2D)          multiple                  2359808   \n",
      "                                                                 \n",
      " batch_normalization_10 (Bat  multiple                 2048      \n",
      " chNormalization)                                                \n",
      "                                                                 \n",
      " activation_10 (Activation)  multiple                  0         \n",
      "                                                                 \n",
      " conv2d_11 (Conv2D)          multiple                  2359808   \n",
      "                                                                 \n",
      " batch_normalization_11 (Bat  multiple                 2048      \n",
      " chNormalization)                                                \n",
      "                                                                 \n",
      " activation_11 (Activation)  multiple                  0         \n",
      "                                                                 \n",
      " conv2d_12 (Conv2D)          multiple                  2359808   \n",
      "                                                                 \n",
      " batch_normalization_12 (Bat  multiple                 2048      \n",
      " chNormalization)                                                \n",
      "                                                                 \n",
      " activation_12 (Activation)  multiple                  0         \n",
      "                                                                 \n",
      " max_pooling2d_4 (MaxPooling  multiple                 0         \n",
      " 2D)                                                             \n",
      "                                                                 \n",
      " dropout_4 (Dropout)         multiple                  0         \n",
      "                                                                 \n",
      " flatten (Flatten)           multiple                  0         \n",
      "                                                                 \n",
      " dense (Dense)               multiple                  262656    \n",
      "                                                                 \n",
      " dropout_5 (Dropout)         multiple                  0         \n",
      "                                                                 \n",
      " dense_1 (Dense)             multiple                  262656    \n",
      "                                                                 \n",
      " dropout_6 (Dropout)         multiple                  0         \n",
      "                                                                 \n",
      " dense_2 (Dense)             multiple                  5130      \n",
      "                                                                 \n",
      "=================================================================\n",
      "Total params: 15,262,026\n",
      "Trainable params: 15,253,578\n",
      "Non-trainable params: 8,448\n",
      "_________________________________________________________________\n"
     ]
    }
   ],
   "source": [
    "# 1，导入模块\n",
    "import tensorflow as tf\n",
    "from tensorflow.keras.layers import Conv2D, BatchNormalization, Activation, MaxPool2D, Dropout, Flatten, Dense\n",
    "from tensorflow.keras import Model\n",
    "# 2，加载数据集\n",
    "(x_train, y_train), (x_test, y_test) = tf.keras.datasets.cifar10.load_data()\n",
    "x_train, x_test = x_train / 255.0, x_test / 255.0\n",
    "# 3，创建网络\n",
    "class VGG16(Model):\n",
    "    def __init__(self):\n",
    "        super(VGG16,self).__init__()\n",
    "        # 层1-卷积层\n",
    "        self.c1 = Conv2D(filters=64, kernel_size=(3, 3), padding='same')  \n",
    "        self.b1 = BatchNormalization()  \n",
    "        self.a1 = Activation('relu')  \n",
    "        # 层2-卷积层\n",
    "        self.c2 = Conv2D(filters=64, kernel_size=(3, 3), padding='same', )\n",
    "        self.b2 = BatchNormalization() \n",
    "        self.a2 = Activation('relu')\n",
    "        self.p1 = MaxPool2D(pool_size=(2, 2), strides=2, padding='same')\n",
    "        self.d1 = Dropout(0.2)\n",
    "        # 层3-卷积层\n",
    "        self.c3 = Conv2D(filters=128, kernel_size=(3, 3), padding='same')\n",
    "        self.b3 = BatchNormalization() \n",
    "        self.a3 = Activation('relu') \n",
    "        # 层4-卷积层\n",
    "        self.c4 = Conv2D(filters=128, kernel_size=(3, 3), padding='same')\n",
    "        self.b4 = BatchNormalization() \n",
    "        self.a4 = Activation('relu') \n",
    "        self.p2 = MaxPool2D(pool_size=(2, 2), strides=2, padding='same')\n",
    "        self.d2 = Dropout(0.2)\n",
    "        # 层5-卷积层\n",
    "        self.c5 = Conv2D(filters=256, kernel_size=(3, 3), padding='same')\n",
    "        self.b5 = BatchNormalization()\n",
    "        self.a5 = Activation('relu')\n",
    "        # 层6-卷积层\n",
    "        self.c6 = Conv2D(filters=256, kernel_size=(3, 3), padding='same')\n",
    "        self.b6 = BatchNormalization()\n",
    "        self.a6 = Activation('relu')\n",
    "        # 层7-卷积层\n",
    "        self.c7 = Conv2D(filters=256, kernel_size=(3, 3), padding='same')\n",
    "        self.b7 = BatchNormalization()\n",
    "        self.a7 = Activation('relu')\n",
    "        self.p3 = MaxPool2D(pool_size=(2, 2), strides=2, padding='same')\n",
    "        self.d3 = Dropout(0.2)\n",
    "        # 层8-卷积层\n",
    "        self.c8 = Conv2D(filters=512, kernel_size=(3, 3), padding='same')\n",
    "        self.b8 = BatchNormalization()\n",
    "        self.a8 = Activation('relu')\n",
    "        # 层9-卷积层\n",
    "        self.c9 = Conv2D(filters=512, kernel_size=(3, 3), padding='same')\n",
    "        self.b9 = BatchNormalization()\n",
    "        self.a9 = Activation('relu')\n",
    "        # 层10-卷积层\n",
    "        self.c10 = Conv2D(filters=512, kernel_size=(3, 3), padding='same')\n",
    "        self.b10 = BatchNormalization()\n",
    "        self.a10 = Activation('relu')\n",
    "        self.p4 = MaxPool2D(pool_size=(2, 2), strides=2, padding='same')\n",
    "        self.d4 = Dropout(0.2)\n",
    "        # 层11-卷积层\n",
    "        self.c11 = Conv2D(filters=512, kernel_size=(3, 3), padding='same')\n",
    "        self.b11 = BatchNormalization()\n",
    "        self.a11 = Activation('relu')\n",
    "        # 层12-卷积层\n",
    "        self.c12 = Conv2D(filters=512, kernel_size=(3, 3), padding='same')\n",
    "        self.b12 = BatchNormalization()\n",
    "        self.a12 = Activation('relu')\n",
    "        # 层13-卷积层\n",
    "        self.c13 = Conv2D(filters=512, kernel_size=(3, 3), padding='same')\n",
    "        self.b13 = BatchNormalization()\n",
    "        self.a13 = Activation('relu')\n",
    "        self.p5 = MaxPool2D(pool_size=(2, 2), strides=2, padding='same')\n",
    "        self.d5 = Dropout(0.2)        \n",
    "        # 拉平层\n",
    "        self.flatten = Flatten()        \n",
    "        # 层14-全连接层\n",
    "        self.f1 = Dense(512, activation='relu')\n",
    "        self.d6 = Dropout(0.2)\n",
    "        # 层15-全连接层\n",
    "        self.f2 = Dense(512, activation='relu')\n",
    "        self.d7 = Dropout(0.2)\n",
    "        # 层16-全连接层\n",
    "        self.f3 = Dense(10, activation='softmax')        \n",
    "    def call(self,x):\n",
    "        x = self.c1(x)\n",
    "        x = self.b1(x)\n",
    "        x = self.a1(x)\n",
    "        x = self.c2(x)\n",
    "        x = self.b2(x)\n",
    "        x = self.a2(x)\n",
    "        x = self.p1(x)\n",
    "        x = self.d1(x)\n",
    "\n",
    "        x = self.c3(x)\n",
    "        x = self.b3(x)\n",
    "        x = self.a3(x)\n",
    "        x = self.c4(x)\n",
    "        x = self.b4(x)\n",
    "        x = self.a4(x)\n",
    "        x = self.p2(x)\n",
    "        x = self.d2(x)\n",
    "\n",
    "        x = self.c5(x)\n",
    "        x = self.b5(x)\n",
    "        x = self.a5(x)\n",
    "        x = self.c6(x)\n",
    "        x = self.b6(x)\n",
    "        x = self.a6(x)\n",
    "        x = self.c7(x)\n",
    "        x = self.b7(x)\n",
    "        x = self.a7(x)\n",
    "        x = self.p3(x)\n",
    "        x = self.d3(x)\n",
    "\n",
    "        x = self.c8(x)\n",
    "        x = self.b8(x)\n",
    "        x = self.a8(x)\n",
    "        x = self.c9(x)\n",
    "        x = self.b9(x)\n",
    "        x = self.a9(x)\n",
    "        x = self.c10(x)\n",
    "        x = self.b10(x)\n",
    "        x = self.a10(x)\n",
    "        x = self.p4(x)\n",
    "        x = self.d4(x)\n",
    "\n",
    "        x = self.c11(x)\n",
    "        x = self.b11(x)\n",
    "        x = self.a11(x)\n",
    "        x = self.c12(x)\n",
    "        x = self.b12(x)\n",
    "        x = self.a12(x)\n",
    "        x = self.c13(x)\n",
    "        x = self.b13(x)\n",
    "        x = self.a13(x)\n",
    "        x = self.p5(x)\n",
    "        x = self.d5(x)\n",
    "\n",
    "        x = self.flatten(x)\n",
    "        x = self.f1(x)\n",
    "        x = self.d6(x)\n",
    "        x = self.f2(x)\n",
    "        x = self.d7(x)\n",
    "        y = self.f3(x)\n",
    "        return y\n",
    "\n",
    "# 实例化模型对象\n",
    "model = VGG16()\n",
    "\n",
    "# 4，配置网络\n",
    "model.compile(\n",
    "    # 优化器\n",
    "    optimizer='adam',\n",
    "    # 损失函数\n",
    "    loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits= False),\n",
    "    # 评测方法\n",
    "    metrics=['sparse_categorical_accuracy']\n",
    ")\n",
    "\n",
    "# 5，训练网络\n",
    "history = model.fit(\n",
    "    x_train, y_train, batch_size=32, epochs=5, \n",
    "    validation_data=(x_test, y_test), validation_freq=1)\n",
    "\n",
    "model.summary()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e6044c99-0741-4378-b2b6-f60c293cc3a9",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
